<template>
  <div id="category">
    <div class="custom-tree-node">
      <div style="height: 38px;">
        <el-switch
          v-model="isBatchDelete"
          active-color="#13ce66"
          inactive-text="批量删除">
        </el-switch>
      </div>

      <el-button v-if="isBatchDelete" type="danger" icon="el-icon-delete" size="mini" circle @click="batchDelete()"></el-button>
    </div>

    <el-tree :data="categories"
             :props="defaultProps"
             show-checkbox node-key="catId"
             :default-expanded-keys="defaultExpandedKeys"
             @node-drop="handleDrop"
             draggable
             ref="node"
             :allow-drop="allowDrop">
    <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button type="text" size="mini" @click="() => append(data)"
                     :style="data.catLevel===3?'':'color: cornflowerblue'"
                     :disabled="data.catLevel===3">添加</el-button>
          <el-button type="text" size="mini" @click="modify(data)"
                     style="color: cornflowerblue">修改</el-button>
          <el-button type="text" size="mini" @click="() => remove(node, data)"
                     :style="data.children.length!==0?'':'color: red'"
                     :disabled="data.children.length!==0">删除</el-button>
        </span>
      </span>
    </el-tree>

    <el-dialog :title="dialogType==='save'?'添加类别':'修改类别'" :visible.sync="dialogFormVisible" center>
      <el-form :model="categoryForm">
        <el-form-item label="类别名称" label-width="120px">
          <el-input v-model="categoryForm.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="商品图标" label-width="120px">
          <el-input v-model="categoryForm.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="商品规格" label-width="120px">
          <el-input v-model="categoryForm.productUnit" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addCategory()">确 定</el-button>
      </div>
    </el-dialog>
  </div>

</template>

<script>
  export default {
    name: "category",
    data() {
      return {
        categories: [],
        defaultExpandedKeys: [],
        dialogFormVisible: false,
        isBatchDelete: false,
        dialogType: 'save',
        categoryForm: {
          catId: null,
          name: '',
          parentCid: 0,
          catLevel: 0,
          showStatus: 1,
          sort: 0,
          icon: '',
          productUnit: ''
        },
        updateMovedData: [],
        defaultProps: {
          children: 'children',
          label: 'name'
        }
      };
    },
    methods: {
      getCategories() {
        this.$http({
          url: this.$http.adornUrl('/product/category/list/tree'),
          method: 'get',
        }).then(({data}) => {
          this.categories = data.data
        })
      },
      append(data) {
        this.dialogType = 'save'
        this.dialogFormVisible = true
        this.categoryForm.parentCid = data.catId
        this.categoryForm.catLevel = data.catLevel + 1

        //恢复默认值
        this.categoryForm.catId = null
        this.categoryForm.name = ''
        this.categoryForm.sort = 0
        this.categoryForm.showStatus = 1
        this.categoryForm.icon = ''
        this.categoryForm.productUnit = ''
      },
      modify(data) {
        this.dialogType = 'update'
        this.dialogFormVisible = true
        this.categoryForm.catId = data.catId
        this.categoryForm.parentCid = data.catId

        //实时得到最新数据
        this.$http({
          url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
          method: 'get'
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.categoryForm.name = data.data.name
            this.categoryForm.icon = data.data.icon
            this.categoryForm.productUnit = data.data.productUnit
          } else {
            this.$message.error(data.msg)
          }
        })
      },
      addCategory() {
        let data = {}
        if (this.dialogType === 'save') {
          data = this.categoryForm
        } else {
          const {catId, name, icon, productUnit} = this.categoryForm
          data = {catId, name, icon, productUnit}
        }

        this.$http({
          url: this.$http.adornUrl(`/product/category/${this.dialogType}`),
          method: this.dialogType === 'save' ? 'post' : 'put',
          data: this.$http.adornData(data, false)
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.$message({
              message: `${this.dialogType === 'save' ? '添加' : '修改'}成功`,
              type: 'success',
              duration: 1500
            })
            this.getCategories()
            this.defaultExpandedKeys = [this.categoryForm.parentCid]
          } else {
            this.$message.error(data.msg)
          }
        })
        this.dialogFormVisible = false
      },
      remove(node, data) {
        const ids = [data.catId]

        this.$confirm(`此操作将永久删除【${data.name}】类别, 是否继续?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'delete',
            data: this.$http.adornData(ids, false)
          }).then(({data}) => {
            if (data && data.code === 0) {
              this.$message({
                message: '删除成功',
                type: 'success',
                duration: 1500
              })

              this.getCategories()
              this.defaultExpandedKeys = [node.parent.data.catId]
            } else {
              this.$message.error(data.msg)
            }
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });

      },
      batchDelete() {
        let deleteData = this.$refs.node.getCheckedNodes()
        let deleteIds = []
        for (let i = 0; i < deleteData.length; i++) {
          deleteIds.push(deleteData[i].catId)
        }

        this.$confirm(`此操作将批量删除所选类别, 是否继续?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'delete',
            data: this.$http.adornData(deleteIds, false)
          }).then(({data}) => {
            if (data && data.code === 0) {
              this.$message({
                message: '批量删除成功',
                type: 'success',
                duration: 1500
              })

              this.getCategories()
            } else {
              this.$message.error(data.msg)
            }
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },
      allowDrop(draggingNode, dropNode, type) {
        let maxDepth = 1;
        maxDepth = this.countNodeDepth(draggingNode, maxDepth)

        if (dropNode.level + maxDepth > 3) {
          return type !== 'inner';
        } else {
          return true;
        }
      },
      countNodeDepth(node, maxDepth) {
        if (node.childNodes != null && node.childNodes.length > 0) {
          maxDepth++
          let originDepth = maxDepth
          for (let i = 0; i < node.childNodes.length; i++) {
            //计算每个子节点的深度，找出最大深度
            let depth = this.countNodeDepth(node.childNodes[i], originDepth)
            if (depth > maxDepth) {
              maxDepth = depth
            }
          }
        }
        return maxDepth
      },
      handleDrop(draggingNode, dropNode, dropType, ev) {
        let parentCid = 0
        let childNodes = null
        if (dropType === 'inner') {
          // 获取父节点ID
          parentCid = dropNode.data.catId
          // 获取需要排序的子节点
          childNodes = dropNode.childNodes
        } else {
          parentCid = dropNode.parent.data.catId === undefined ? 0 : dropNode.parent.data.catId
          childNodes = dropNode.parent.childNodes
        }

        this.updateMovedData = []
        //更新排序字段sort
        for (let i = 0; i < childNodes.length; i++) {
          if (childNodes[i].data.catId === draggingNode.data.catId) {
            const catLevel = childNodes[i].level
            //更新层级
            if (childNodes[i].level !== draggingNode.level) {
              this.updateChildNodesLevel(childNodes[i])
            }
            this.updateMovedData.push({catId: childNodes[i].data.catId, sort: i, parentCid, catLevel})
          } else {
            this.updateMovedData.push({catId: childNodes[i].data.catId, sort: i})
          }
        }

        this.$http({
          url: this.$http.adornUrl('/product/category/update/sort'),
          method: 'put',
          data: this.$http.adornData(this.updateMovedData, false)
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.$message({
              message: '移动成功',
              type: 'success',
              duration: 1500
            })

            this.getCategories()
            this.defaultExpandedKeys = [parentCid]
          } else {
            this.$message.error(data.msg)
          }
        })
      },
      updateChildNodesLevel(node) {
        if (node.childNodes !== null && node.childNodes.length > 0) {
          for (let i = 0; i < node.childNodes.length; i++) {
            this.updateMovedData.push({catId: node.childNodes[i].data.catId, catLevel: node.childNodes[i].level})
            this.updateChildNodesLevel(node.childNodes[i])
          }
        }
      }
    },
    created() {
      this.getCategories();
    }
  }
</script>

<style lang="scss" scoped>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }


</style>
